/**
 * server.js
 * 后端服务主文件 - PostgreSQL数据库版本
 * 功能：提供菜品管理API、用户认证、订单管理
 */

const express = require('express');
const path = require('path');
const fs = require('fs');
const helmet = require('helmet');
const cors = require('cors');
const winston = require('winston');
const { Pool } = require('pg');

const app = express();

// ==================== 日志配置 ====================
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
    winston.format.errors({ stack: true }),
    winston.format.splat(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.Console({
      format: winston.format.combine(
        winston.format.colorize(),
        winston.format.printf(({ level, message, timestamp, stack }) => {
          if (stack) {
            return `${timestamp} ${level}: ${message}\n${stack}`;
          }
          return `${timestamp} ${level}: ${message}`;
        })
      )
    })
  ]
});

// ==================== 全局异常捕获 ====================
process.on('uncaughtException', (err) => {
  logger.error('未捕获的异常:', err);
});

process.on('unhandledRejection', (reason, promise) => {
  logger.error('未处理的Promise拒绝:', reason);
});

// ==================== 中间件配置 ====================
app.use(helmet({
  contentSecurityPolicy: false,
  frameguard: false
}));

app.use(cors());
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));

// ==================== 请求日志 ====================
app.use((req, res, next) => {
  const start = Date.now();
  res.on('finish', () => {
    const duration = Date.now() - start;
    logger.info(`${req.method} ${req.path} - ${res.statusCode} - ${duration}ms`);
  });
  next();
});

// ==================== 静态文件服务 ====================
const publicDir = path.resolve(__dirname, '../frontend/public');
const distDir = path.resolve(__dirname, '../frontend/dist');
const publicPath = fs.existsSync(publicDir) ? publicDir : distDir;

if (fs.existsSync(publicPath)) {
  app.use(express.static(publicPath));
  logger.info(`静态文件目录: ${publicPath}`);
} else {
  logger.warn(`静态文件目录不存在: ${publicPath}`);
}

// ==================== 从db_config.txt读取数据库配置 ====================
const loadDatabaseConfig = () => {
  try {
    const dbConfigPath = path.join(__dirname, 'db_config.txt');
    
    if (!fs.existsSync(dbConfigPath)) {
      logger.warn('⚠️ 数据库配置文件不存在，使用默认配置');
      return {
        DB_USER: 'postgres',
        DB_HOST: 'localhost',
        DB_NAME: 'restaurant_db',
        DB_PASSWORD: 'postgres',
        DB_PORT: '5432'
      };
    }

    const configContent = fs.readFileSync(dbConfigPath, 'utf8').trim();
    const dbConfig = configContent.split('\n').reduce((config, line) => {
      const trimmedLine = line.trim();
      if (trimmedLine && !trimmedLine.startsWith('#')) {
        const [key, ...valueParts] = trimmedLine.split('=');
        const value = valueParts.join('=').trim();
        if (key && value) {
          config[key.trim()] = value;
        }
      }
      return config;
    }, {});

    logger.info('✓ 数据库配置加载成功');
    return dbConfig;
  } catch (error) {
    logger.error('× 加载数据库配置失败:', error.message);
    return {
      DB_USER: 'postgres',
      DB_HOST: 'localhost',
      DB_NAME: 'restaurant_db',
      DB_PASSWORD: 'postgres',
      DB_PORT: '5432'
    };
  }
};

const dbConfig = loadDatabaseConfig();

// ==================== PostgreSQL数据库连接 ====================
const pool = new Pool({
  user: dbConfig.DB_USER,
  host: dbConfig.DB_HOST,
  database: dbConfig.DB_NAME,
  password: dbConfig.DB_PASSWORD,
  port: parseInt(dbConfig.DB_PORT) || 5432,
});

// 测试数据库连接
pool.query('SELECT NOW()', (err, res) => {
  if (err) {
    logger.error('数据库连接失败:', err.message);
  } else {
    logger.info('数据库连接成功:', res.rows[0].now);
  }
});

// ==================== 数据库初始化（统一表结构） ====================
const initDatabase = async () => {
  try {
    logger.info('开始初始化数据库表结构...');

    // 创建菜品表（统一使用SERIAL主键）
    await pool.query(`
      CREATE TABLE IF NOT EXISTS dishes (
        id SERIAL PRIMARY KEY,
        name VARCHAR(255) NOT NULL,
        price DECIMAL(10, 2) NOT NULL,
        description TEXT,
        category VARCHAR(100),
        recipe TEXT,
        weather_condition VARCHAR(50) DEFAULT 'normal',
        image_url TEXT,
        is_active BOOLEAN DEFAULT TRUE,
        created_at BIGINT NOT NULL,
        updated_at BIGINT
      )
    `);
    logger.info('✓ dishes 表初始化完成');

    // 创建用户表（统一使用SERIAL主键）
    await pool.query(`
      CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        username VARCHAR(100) UNIQUE NOT NULL,
        password VARCHAR(255) NOT NULL,
        role VARCHAR(50) NOT NULL,
        created_at BIGINT NOT NULL
      )
    `);
    logger.info('✓ users 表初始化完成');

    // 创建订单表（统一使用SERIAL主键）
    await pool.query(`
      CREATE TABLE IF NOT EXISTS orders (
        id SERIAL PRIMARY KEY,
        order_id VARCHAR(255) UNIQUE NOT NULL,
        items JSONB NOT NULL,
        user_info JSONB NOT NULL,
        total_price DECIMAL(10, 2) NOT NULL,
        status VARCHAR(50) DEFAULT 'pending',
        created_at BIGINT NOT NULL,
        updated_at BIGINT,
        estimated_time VARCHAR(100)
      )
    `);
    logger.info('✓ orders 表初始化完成');

    // 插入默认用户（如果不存在）
    const { rows: existingUsers } = await pool.query('SELECT COUNT(*) as count FROM users');
    if (parseInt(existingUsers[0].count) === 0) {
      await pool.query(`
        INSERT INTO users (username, password, role, created_at) VALUES
        ('女王', '20031013', 'customer', ${Date.now()}),
        ('御厨', '20030215', 'kitchen', ${Date.now()})
      `);
      logger.info('✓ 默认用户数据初始化完成');
    }

    // 插入默认菜品（如果不存在）
    const { rows: existingDishes } = await pool.query('SELECT COUNT(*) as count FROM dishes');
    if (parseInt(existingDishes[0].count) === 0) {
      const defaultDishes = [
        {
          name: '宫保鸡丁',
          price: 38.00,
          description: '经典川菜，鸡肉鲜嫩，花生酥脆，酸甜微辣',
          category: '热菜',
          recipe: '1. 鸡肉切丁腌制\\n2. 花生炸香备用\\n3. 热锅爆炒调味\\n4. 装盘上桌',
          weather_condition: 'normal',
          image_url: 'https://hpi-hub.tos-cn-beijing.volces.com/static/batch_14/1757354850592-5169.jpg',
          is_active: true,
          created_at: Date.now()
        },
        {
          name: '麻婆豆腐',
          price: 28.00,
          description: '经典川菜，豆腐嫩滑，麻辣鲜香',
          category: '热菜',
          recipe: '1. 豆腐切块焯水\\n2. 肉末炒香\\n3. 加入豆瓣酱调味\\n4. 煮制入味',
          weather_condition: 'cold',
          image_url: 'https://hpi-hub.tos-cn-beijing.volces.com/static/batch_14/1757354850592-5169.jpg',
          is_active: true,
          created_at: Date.now()
        },
        {
          name: '糖醋排骨',
          price: 48.00,
          description: '酸甜可口，外酥里嫩，老少皆宜',
          category: '热菜',
          recipe: '1. 排骨切块腌制\\n2. 油炸至金黄\\n3. 糖醋汁收汁\\n4. 撒芝麻装盘',
          weather_condition: 'normal',
          image_url: 'https://hpi-hub.tos-cn-beijing.volces.com/static/batch_14/1757354850592-5169.jpg',
          is_active: true,
          created_at: Date.now()
        },
        {
          name: '清炒时蔬',
          price: 18.00,
          description: '新鲜蔬菜，清淡爽口，健康营养',
          category: '素菜',
          recipe: '1. 蔬菜洗净切段\\n2. 热锅快炒\\n3. 简单调味\\n4. 保持脆嫩',
          weather_condition: 'hot',
          image_url: 'https://hpi-hub.tos-cn-beijing.volces.com/static/batch_14/1757354850592-5169.jpg',
          is_active: true,
          created_at: Date.now()
        },
        {
          name: '酸辣汤',
          price: 15.00,
          description: '酸辣开胃，暖胃驱寒',
          category: '汤品',
          recipe: '1. 高汤煮沸\\n2. 加入食材\\n3. 调味勾芡\\n4. 淋香油出锅',
          weather_condition: 'cold',
          image_url: 'https://hpi-hub.tos-cn-beijing.volces.com/static/batch_14/1757354850592-5169.jpg',
          is_active: true,
          created_at: Date.now()
        }
      ];

      for (const dish of defaultDishes) {
        await pool.query(`
          INSERT INTO dishes (name, price, description, category, recipe, weather_condition, image_url, is_active, created_at)
          VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
        `, [dish.name, dish.price, dish.description, dish.category, dish.recipe, dish.weather_condition, dish.image_url, dish.is_active, dish.created_at]);
      }
      logger.info('✓ 默认菜品数据初始化完成');
    }

    logger.info('='.repeat(60));
    logger.info('数据库表结构初始化完成');
    logger.info('='.repeat(60));
  } catch (error) {
    logger.error('× 数据库表初始化失败:', error.message);
    logger.warn('⚠️ 数据库初始化失败不会阻塞程序启动');
  }
};

initDatabase();

// ==================== 内存会话存储 ====================
const sessions = new Map();

// ==================== API路由 ====================

/**
 * 用户登录接口
 */
app.post('/api/auth/login', async (req, res) => {
  try {
    const { username, password } = req.body;

    if (!username || !password) {
      return res.status(400).json({
        success: false,
        message: '用户名和密码不能为空'
      });
    }

    const { rows } = await pool.query(
      'SELECT * FROM users WHERE username = $1 AND password = $2',
      [username, password]
    );

    if (rows.length === 0) {
      logger.warn(`登录失败: 用户名或密码错误 - ${username}`);
      return res.status(401).json({
        success: false,
        message: '用户名或密码错误'
      });
    }

    const user = rows[0];
    const token = `token_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    const sessionData = {
      userId: user.id,
      username: user.username,
      role: user.role,
      loginTime: Date.now()
    };

    sessions.set(token, sessionData);

    logger.info(`用户登录成功: ${username} (${user.role})`);

    res.json({
      success: true,
      message: '登录成功',
      data: {
        token,
        user: {
          id: user.id,
          username: user.username,
          role: user.role
        }
      }
    });
  } catch (error) {
    logger.error('登录接口错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
});

/**
 * 用户退出接口
 */
app.post('/api/auth/logout', (req, res) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');

    if (token && sessions.has(token)) {
      const session = sessions.get(token);
      logger.info(`用户退出: ${session.username}`);
      sessions.delete(token);
    }

    res.json({
      success: true,
      message: '退出成功'
    });
  } catch (error) {
    logger.error('退出接口错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
});

/**
 * 验证Token接口
 */
app.get('/api/auth/verify', (req, res) => {
  try {
    const token = req.headers.authorization?.replace('Bearer ', '');

    if (!token || !sessions.has(token)) {
      return res.status(401).json({
        success: false,
        message: 'Token无效或已过期'
      });
    }

    const session = sessions.get(token);

    res.json({
      success: true,
      data: {
        userId: session.userId,
        username: session.username,
        role: session.role
      }
    });
  } catch (error) {
    logger.error('验证Token错误:', error);
    res.status(500).json({
      success: false,
      message: '服务器内部错误'
    });
  }
});

/**
 * 获取所有菜品
 * GET /api/dishes
 */
app.get('/api/dishes', async (req, res) => {
  try {
    const { rows } = await pool.query('SELECT * FROM dishes ORDER BY created_at DESC');
    res.json({
      success: true,
      data: rows
    });
  } catch (error) {
    logger.error('获取菜品列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取菜品列表失败',
      error: error.message
    });
  }
});

/**
 * 根据ID获取菜品详情
 * GET /api/dishes/:id
 */
app.get('/api/dishes/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const { rows } = await pool.query('SELECT * FROM dishes WHERE id = $1', [id]);

    if (rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: '菜品不存在'
      });
    }

    res.json({
      success: true,
      data: rows[0]
    });
  } catch (error) {
    logger.error('获取菜品详情失败:', error);
    res.status(500).json({
      success: false,
      message: '获取菜品详情失败',
      error: error.message
    });
  }
});

/**
 * 创建新菜品
 * POST /api/dishes
 */
app.post('/api/dishes', async (req, res) => {
  try {
    const { name, price, description, category, recipe, weatherCondition, imageUrl } = req.body;

    if (!name || !price || !description || !category) {
      return res.status(400).json({
        success: false,
        message: '菜品名称、价格、描述和分类不能为空'
      });
    }

    const priceNum = parseFloat(price);
    if (isNaN(priceNum) || priceNum <= 0) {
      return res.status(400).json({
        success: false,
        message: '价格必须是大于0的有效数字'
      });
    }

    const created_at = Date.now();

    const { rows } = await pool.query(`
      INSERT INTO dishes (name, price, description, category, recipe, weather_condition, image_url, is_active, created_at)
      VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
      RETURNING *
    `, [
      name.trim(),
      priceNum,
      description.trim(),
      category.trim(),
      recipe?.trim() || '暂无制作步骤',
      weatherCondition || 'normal',
      imageUrl || 'https://hpi-hub.tos-cn-beijing.volces.com/static/batch_14/1757354850592-5169.jpg',
      true,
      created_at
    ]);

    logger.info(`菜品创建成功: ${name} (ID: ${rows[0].id})`);

    res.status(201).json({
      success: true,
      message: '菜品创建成功',
      data: rows[0]
    });
  } catch (error) {
    logger.error('创建菜品失败:', error);
    res.status(500).json({
      success: false,
      message: '创建菜品失败',
      error: error.message
    });
  }
});

/**
 * 更新菜品信息
 * PUT /api/dishes/:id
 */
app.put('/api/dishes/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const { name, price, description, category, recipe, weather_condition, image_url } = req.body;

    const updated_at = Date.now();

    const { rows } = await pool.query(`
      UPDATE dishes
      SET name = $1, price = $2, description = $3, category = $4, recipe = $5,
          weather_condition = $6, image_url = $7, updated_at = $8
      WHERE id = $9
      RETURNING *
    `, [
      name,
      parseFloat(price),
      description,
      category,
      recipe,
      weather_condition,
      image_url,
      updated_at,
      id
    ]);

    if (rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: '菜品不存在'
      });
    }

    logger.info(`菜品更新成功: ${name} (ID: ${id})`);

    res.json({
      success: true,
      message: '菜品更新成功',
      data: rows[0]
    });
  } catch (error) {
    logger.error('更新菜品失败:', error);
    res.status(500).json({
      success: false,
      message: '更新菜品失败',
      error: error.message
    });
  }
});

/**
 * 更新菜品上架状态
 * PATCH /api/dishes/:id/status
 */
app.patch('/api/dishes/:id/status', async (req, res) => {
  try {
    const { id } = req.params;
    const { is_active } = req.body;

    if (typeof is_active !== 'boolean') {
      return res.status(400).json({
        success: false,
        message: 'is_active 必须是布尔值'
      });
    }

    const updated_at = Date.now();

    const { rows } = await pool.query(`
      UPDATE dishes
      SET is_active = $1, updated_at = $2
      WHERE id = $3
      RETURNING *
    `, [is_active, updated_at, id]);

    if (rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: '菜品不存在'
      });
    }

    logger.info(`菜品状态更新: ${rows[0].name} - ${is_active ? '已上架' : '已下架'} (ID: ${id})`);

    res.json({
      success: true,
      message: '菜品状态更新成功',
      data: rows[0]
    });
  } catch (error) {
    logger.error('更新菜品状态失败:', error);
    res.status(500).json({
      success: false,
      message: '更新菜品状态失败',
      error: error.message
    });
  }
});

/**
 * 删除菜品
 * DELETE /api/dishes/:id
 */
app.delete('/api/dishes/:id', async (req, res) => {
  try {
    const { id } = req.params;

    const { rows } = await pool.query('DELETE FROM dishes WHERE id = $1 RETURNING *', [id]);

    if (rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: '菜品不存在'
      });
    }

    logger.info(`菜品删除成功: ${rows[0].name} (ID: ${id})`);

    res.json({
      success: true,
      message: '菜品删除成功'
    });
  } catch (error) {
    logger.error('删除菜品失败:', error);
    res.status(500).json({
      success: false,
      message: '删除菜品失败',
      error: error.message
    });
  }
});

/**
 * 创建订单
 * POST /api/orders
 */
app.post('/api/orders', async (req, res) => {
  try {
    const { items, userInfo, totalPrice } = req.body;

    if (!items || !Array.isArray(items) || items.length === 0) {
      return res.status(400).json({
        success: false,
        message: '订单项不能为空'
      });
    }

    if (!userInfo || !userInfo.name || !userInfo.phone || !userInfo.address) {
      return res.status(400).json({
        success: false,
        message: '用户信息不完整'
      });
    }

    const totalPriceNum = parseFloat(totalPrice);
    if (isNaN(totalPriceNum) || totalPriceNum <= 0) {
      return res.status(400).json({
        success: false,
        message: '订单总价必须是大于0的有效数字'
      });
    }

    const order_id = `ORD${Date.now()}${Math.random().toString(36).substr(2, 9).toUpperCase()}`;
    const created_at = Date.now();

    const { rows } = await pool.query(`
      INSERT INTO orders (order_id, items, user_info, total_price, status, created_at, estimated_time)
      VALUES ($1, $2, $3, $4, $5, $6, $7)
      RETURNING *
    `, [
      order_id,
      JSON.stringify(items),
      JSON.stringify(userInfo),
      totalPriceNum,
      'pending',
      created_at,
      '30-45分钟'
    ]);

    logger.info(`订单创建成功: ${order_id} - 总价: ¥${totalPrice} - 客户: ${userInfo.name}`);

    res.status(201).json({
      success: true,
      message: '订单创建成功',
      data: {
        ...rows[0],
        items: JSON.parse(rows[0].items),
        user_info: JSON.parse(rows[0].user_info)
      }
    });
  } catch (error) {
    logger.error('创建订单失败:', error);
    res.status(500).json({
      success: false,
      message: '订单提交失败，请检查网络并重试',
      error: error.message
    });
  }
});

/**
 * 获取所有订单
 * GET /api/orders
 */
app.get('/api/orders', async (req, res) => {
  try {
    const { rows } = await pool.query('SELECT * FROM orders ORDER BY created_at DESC');

    const orders = rows.map(order => ({
      ...order,
      items: JSON.parse(order.items),
      user_info: JSON.parse(order.user_info)
    }));

    res.json({
      success: true,
      data: orders
    });
  } catch (error) {
    logger.error('获取订单列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取订单列表失败',
      error: error.message
    });
  }
});

/**
 * 更新订单状态
 * PATCH /api/orders/:id/status
 */
app.patch('/api/orders/:id/status', async (req, res) => {
  try {
    const { id } = req.params;
    const { status } = req.body;

    const updated_at = Date.now();

    const { rows } = await pool.query(`
      UPDATE orders
      SET status = $1, updated_at = $2
      WHERE id = $3 OR order_id = $3
      RETURNING *
    `, [status, updated_at, id]);

    if (rows.length === 0) {
      return res.status(404).json({
        success: false,
        message: '订单不存在'
      });
    }

    logger.info(`订单状态更新: ${rows[0].order_id} - ${status}`);

    res.json({
      success: true,
      message: '订单状态更新成功',
      data: {
        ...rows[0],
        items: JSON.parse(rows[0].items),
        user_info: JSON.parse(rows[0].user_info)
      }
    });
  } catch (error) {
    logger.error('更新订单状态失败:', error);
    res.status(500).json({
      success: false,
      message: '更新订单状态失败',
      error: error.message
    });
  }
});

/**
 * 获取系统信息接口
 */
app.get('/api/system/info', (req, res) => {
  res.json({
    success: true,
    data: {
      name: '御膳房点单系统',
      version: '2.0.0',
      mode: 'PostgreSQL',
      description: '基于天气推荐的智能点餐系统',
      features: [
        '天气推荐',
        '菜品浏览',
        '购物车管理',
        '订单提交',
        '后厨管理',
        '云端数据同步'
      ]
    }
  });
});

// ==================== 处理前端路由 ====================
app.get('*', (req, res) => {
  if (req.path.startsWith('/api/')) {
    return res.status(404).json({
      success: false,
      message: 'API接口不存在'
    });
  }

  const filePath = path.join(publicPath, req.path);
  
  if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {
    return res.sendFile(filePath);
  }

  const indexPath = path.join(publicPath, 'index.html');
  if (fs.existsSync(indexPath)) {
    return res.sendFile(indexPath);
  }

  res.status(404).json({
    success: false,
    message: '页面不存在'
  });
});

// ==================== 错误处理中间件 ====================
app.use((err, req, res, next) => {
  logger.error('服务器错误:', err);
  res.status(500).json({
    success: false,
    message: '服务器内部错误',
    error: process.env.NODE_ENV === 'development' ? err.message : undefined
  });
});

// ==================== 启动服务器 ====================
const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  logger.info('='.repeat(60));
  logger.info('御膳房点单系统 - 服务器启动成功');
  logger.info('='.repeat(60));
  logger.info(`服务器运行在: http://localhost:${PORT}`);
  logger.info(`环境: ${process.env.NODE_ENV || 'development'}`);
  logger.info(`数据存储: PostgreSQL (云端数据库)`);
  logger.info(`静态文件: ${publicPath}`);
  logger.info('='.repeat(60));
  logger.info('可用账户:');
  logger.info('  - 点菜窗口: 女王 / 20031013');
  logger.info('  - 后厨窗口: 御厨 / 20030215');
  logger.info('='.repeat(60));
});

// ==================== 优雅关闭 ====================
process.on('SIGTERM', () => {
  logger.info('收到SIGTERM信号，准备关闭服务器...');
  sessions.clear();
  pool.end(() => {
    logger.info('数据库连接已关闭');
    logger.info('服务器已关闭');
  });
});

process.on('SIGINT', () => {
  logger.info('收到SIGINT信号，准备关闭服务器...');
  sessions.clear();
  pool.end(() => {
    logger.info('数据库连接已关闭');
    logger.info('服务器已关闭');
  });
});

module.exports = app;